﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading;

namespace WeiXinSDK.Core
{
    public class DBFactory:IDisposable
    {
        private static string dbProviderName = ConfigurationManager.AppSettings["DbHelperProvider"];
        private static string dbConnectionString = ConfigurationManager.AppSettings["DbHelperConnectionString"];

        public DbProviderFactory dbfactory = null;
        public DbConnection connection = null;
        public DbTransaction dbTrans = null;

        private DBFactory()
        {
            dbfactory = DbProviderFactories.GetFactory(dbProviderName);
            connection = dbfactory.CreateConnection();
            connection.ConnectionString = dbConnectionString;
            connection.Open();
        }

        private class CurrentSession
        {
            public static ThreadLocal<DBFactory> session = new ThreadLocal<DBFactory>();
            public static DBFactory DBFactory
            {
                get
                {
                    DBFactory s = session.Value;
                    if (s == null)
                    {
                        s = new DBFactory();
                        session.Value = s;
                    }
                    return s;
                }
            }


            public static void Remove()
            {
                session.Value = null;
            }
        }

        //.NET4.0之前的版本使用
        //private class CurrentSession
        //{
        //    [ThreadStaticAttribute]
        //    public static DBFactory session = null;        
        //    public static DBFactory DBFactory
        //    {
        //        get
        //        {
        //            DBFactory s = session;
        //            if (s == null)
        //            {
        //                s = new DBFactory();
        //                session = s;
        //            }
        //            return s;
        //        }
        //    }
        //    public static void Remove()
        //    {
        //        session = null;
        //    }
        //}

        /// <summary>
        /// 获得当前线程的DBFactory
        /// </summary>
        /// <returns></returns>
        public static DBFactory GetCurrentDBFactory()
        {
            return CurrentSession.DBFactory;
        }


        /// <summary>
        /// 开始事务
        /// </summary>
        public void BeginTransaction()
        {
            dbTrans = connection.BeginTransaction();
        }

        /// <summary>
        /// 设置DbTransaction
        /// </summary>
        /// <param name="cmd"></param>
        public void SetTransaction(DbCommand cmd)
        {
            if (dbTrans != null) cmd.Transaction = dbTrans;
        }

        /// <summary>
        /// 提交事务
        /// </summary>
        public void Commit()
        {
            dbTrans.Commit();
        }


        /// <summary>
        /// 回滚事务
        /// </summary>
        public void RollBack()
        {
            dbTrans.Rollback();
        }


        /// <summary>
        /// 关闭数据库连接，一般不需手动调用，实例销毁自动执行
        /// </summary>
        private void Colse()
        {
            if (connection.State == System.Data.ConnectionState.Open)
            {
                connection.Close();
            }
            CurrentSession.Remove();
        }


        /// <summary>
        /// 销毁实例的操作，关闭数据库连接
        /// 不需要事务的时候显示调用关闭连接，如在执行事务则通过DbFactory自动回收
        /// </summary>
        public void Dispose()
        {
            if (dbTrans == null)
            {
                Colse();
            }
        }
    }
}
